#ifndef DOCUMENT_MANAGER_H
#define DOCUMENT_MANAGER_H

#include <icontainerdocument.h>
#include <ieditor.h>
#include <ilinkeddocument.h>
#include <isessionprovider.h>

#include <QtCore/QHash>
#include <QtCore/QObject>
#include <QtCore/QSharedPointer>

namespace core
{
class IEditor;
class IPersistenceAssistant;
}

namespace swp
{

class DocumentManager : public QObject, public core::ISessionProvider
{
    Q_OBJECT

    enum DialogAction
    {
        Yes,
        No,
        Cancel
    };

public:
    enum RequireLinks
    {
        None,
        One,
        Many
    };

public:
    static DocumentManager* getInstance();
    static void destroy();

public:
    QList<QSharedPointer<core::IContainerDocument> > openedProjects() const;
    QList<QSharedPointer<core::IDocument> > openedDocuments() const;
    bool isOpenedToMemory(
        const QSharedPointer<core::IDocument>& document) const;

private:
    DocumentManager();
    ~DocumentManager();

    QSharedPointer<core::IPersistenceAssistant> getNativeAssistant(
        const QSharedPointer<core::IDocument>& document) const;
    DialogAction askForSave(const QSharedPointer<core::IDocument>&
        document) const;
    DialogAction askForRemove(const QSharedPointer<core::IDocument>&
            document) const;
    DialogAction askForDelete(const QSharedPointer<core::IDocument>&
            document) const;
    DialogAction askForSaveLinks(const QSharedPointer<core::IDocument>&
        document, int linksCount) const;
    QString getStorage(const QString& title,
        bool& ok) const;
    bool saveChildDocuments(const QSharedPointer<core::IContainerDocument>&
        project, const QString& storage, bool& canceled);
    void deleteChildDocuments(const QSharedPointer<core::IContainerDocument>&
        project);
    void removeChildDocuments(const QSharedPointer<core::IContainerDocument>&
        project);
    QString getCategory(const QSharedPointer<core::IContainerDocument>&
        project, const core::MimeType& documentMimeType) const;
    void closeAllLiveAssistans(const QSharedPointer<core::IContainerDocument>&
        project) const;
    void closeAllOpenedEditors(const QSharedPointer<core::IContainerDocument>&
        project);

    void removeFromOpened(const QSharedPointer<core::IDocument>& document);

    QString camelCase(const QString& text) const;

    bool subSave(const QSharedPointer<core::IDocument>&
        document);
    void openProject(const QUrl& url, const QString& storageName);

    QList<QSharedPointer<core::IDocument> > getLinks(
        const QSharedPointer<core::IContainerDocument>& project,
        const QSharedPointer<core::ILinkedDocument>& document,
        RequireLinks type, bool reqValidity, bool& ok) const;

signals:
    void projectCreated(const QSharedPointer<core::IDocument> project);
    void projectOpened(const QSharedPointer<core::IDocument> project);
    void documentSaved(const QSharedPointer<core::IDocument> project);
    void documentAdded(const QSharedPointer<core::IDocument> project,
        const QSharedPointer<core::IDocument> document);
    void documentRemoved(const QSharedPointer<core::IDocument> project,
        const QSharedPointer<core::IDocument> document);
    void documentRemoved(const QSharedPointer<core::IDocument> document);
    void documentOpened(const QSharedPointer<core::IDocument> document);
    void documentClosed(const QSharedPointer<core::IDocument> document);
    void documentClosed(const QSharedPointer<core::IEditor> editor);

public slots:
    void newProject();
    void openProject();
    void openProject(const QString& url, const QString& storage);
    void addDocument(const QSharedPointer<core::IDocument>& project,
        const QList<core::MimeType>& possibilites, uint requireLinks,
        bool requireValidity = false);
    void addDocument(const QSharedPointer<core::IDocument>& project,
        const QSharedPointer<core::IDocument>& document,
        uint requireLinks, bool requireValidity = false);
    void removeDocument(const QSharedPointer<core::IDocument>& project,
        const QSharedPointer<core::IDocument>& document, bool force = false);
    void deleteDocument(const QSharedPointer<core::IDocument>& document);
    void openDocument(const QSharedPointer<core::IDocument>& document);
    void openDocumentToMemory(
        const QSharedPointer<core::IDocument>& document);
    void saveDocument(const QSharedPointer<core::IDocument>& document);
    void closeDocument(const QSharedPointer<core::IDocument>& document,
        bool* canceled = 0);
    void closeDocument(const QSharedPointer<core::IEditor>& editor);
    void moveDocument(const QSharedPointer<core::IDocument>& project,
        const QSharedPointer<core::IDocument>& document);
    void checkCleanState(const QSharedPointer<core::IDocument>& document);

private:
    QHash<QString, QString> m_mimeTypeToNameMapping;
    QList<QSharedPointer<core::IDocument> > m_openedDocuments;
    QList<QSharedPointer<core::IDocument> >m_openedDocumentsInMemory;
};

} // namespace swp

#endif
